package com.vcredit.creditcat.manager.creditassure;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.util.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.alibaba.dubbo.config.annotation.Service;
import com.opensymphony.oscache.util.StringUtil;
import com.vcredit.bird.enumtype.MobileStatusEnum;
import com.vcredit.bird.service.foreignTradeCompliance.ForeignTradeComplianceService;
import com.vcredit.bird.vo.foreignTradeCompliance.AssureParams;
import com.vcredit.bird.vo.foreignTradeCompliance.AssureSubmitParam;
import com.vcredit.bird.vo.foreignTradeCompliance.AssureSubmitResponse;
import com.vcredit.bird.vo.foreignTradeCompliance.ComplianceApplyInfo;
import com.vcredit.bird.vo.foreignTradeCompliance.ComplianceApplyResponse;
import com.vcredit.bird.vo.foreignTradeCompliance.ComplianceParam;
import com.vcredit.bird.vo.foreignTradeCompliance.DynamicParams;
import com.vcredit.bird.vo.foreignTradeCompliance.ForeignSubmitParam;
import com.vcredit.bird.vo.foreignTradeCompliance.InputVbs;
import com.vcredit.bird.vo.foreignTradeCompliance.PreAuditParam;
import com.vcredit.bird.vo.foreignTradeCompliance.PreAuditResponse;
import com.vcredit.bird.vo.foreignTradeCompliance.ReportStateResponse;
import com.vcredit.bird.vo.foreignTradeCompliance.ScoreInfo;
import com.vcredit.creditcat.api.IForeignTradeComplianceManager;
import com.vcredit.creditcat.dto.foreignTradeCompliance.QueryResponse;
import com.vcredit.creditcat.dto.resource.ResourceDto;
import com.vcredit.creditcat.enumtype.AssureStatusEnum;
import com.vcredit.creditcat.enumtype.AuthItemEnum;
import com.vcredit.creditcat.enumtype.ProductBusTypeEnum;
import com.vcredit.creditcat.enumtype.ResourceTypeEnum;
import com.vcredit.creditcat.manager.CreditCatProcessManager;
import com.vcredit.creditcat.manager.resource.FtpResourceManager;
import com.vcredit.creditcat.model.AuthIdentity;
import com.vcredit.creditcat.model.AuthItem;
import com.vcredit.creditcat.model.AuthLog;
import com.vcredit.creditcat.model.AuthMobile;
import com.vcredit.creditcat.model.AuthPersonalInfo;
import com.vcredit.creditcat.model.AuthSecredit;
import com.vcredit.creditcat.model.CreditAssure;
import com.vcredit.creditcat.model.Cust;
import com.vcredit.creditcat.model.CustAccount;
import com.vcredit.creditcat.service.AuthIdentityService;
import com.vcredit.creditcat.service.AuthLogService;
import com.vcredit.creditcat.service.AuthMobileService;
import com.vcredit.creditcat.service.AuthPersonalInfoService;
import com.vcredit.creditcat.service.AuthSecreditService;
import com.vcredit.creditcat.service.CreditAssureService;
import com.vcredit.creditcat.service.CustAccountService;
import com.vcredit.creditcat.service.CustService;
import com.vcredit.creditcat.service.MerchantProductService;
import com.vcredit.creditcat.util.ConcurrentDateUtil;
import com.vcredit.creditcat.util.IdcardUtils;
import com.vcredit.creditcat.util.Utility;
import com.vcredit.framework.annotation.Log;
import com.vcredit.framework.util.Base64Util;
import com.vcredit.framework.util.JacksonUtil;


@Service(protocol = { "protocol1" }, version = "1.0")
public class ForeignTradeComplianceManager implements IForeignTradeComplianceManager {
	
	/*
	* 外贸征信开关，为1时使用外贸征信，为0时使用担保征信
	*/
	/*@Value("${foreignCreditOpenFlag}")
    private int foreignCreditOpenFlag;*/

	@Value("${product.kind}")
    private String productKind;
	@Value("${resource.down.url}")
	private String resDownUrl;
	@Autowired
	private CustService custService;
	@Autowired
	private CustAccountService custAccountService;
	@Autowired
	private ForeignTradeComplianceService foreignTradeComplianceService;
	@Autowired
	private AuthIdentityService authIdentityService;
	@Autowired
	private CreditAssureService creditAssureService;
	@Autowired
	private CreditCatProcessManager creditCatProcessManager;

	@Autowired
	private FtpResourceManager ftpResourceManager;

	@Autowired
	private AuthLogService authLogService;
	
	@Autowired
	private AuthSecreditService authSecreditService;
	
	@Autowired
	private AuthPersonalInfoService authPersonalInfoService;
	
	@Autowired
	private MerchantProductService merchantProductService;
	
	@Autowired
	private AuthMobileService authMobileService;
	
	@Override
	public void signatureImgUpload(String signPhotoData, Long productId,Long lastProccessId) throws Exception {
		ResourceDto resourceDto = ftpResourceManager.upload(
				ResourceTypeEnum.IMG, 
				"signature.jpg",
				Base64.decodeBase64(signPhotoData));
		if(null != resourceDto){
			CreditAssure ca = new CreditAssure();						
			ca.setSignatureImg(resourceDto.getResourceCode());
			ca.setAssureStatus(AssureStatusEnum.Sign.getCode());
			ca.setSignTime(new Date());
			if(productId==0){
				productId = 6L; //默认给信用花
			}
			ca.setProductId(productId);
			CreditAssure creditAssure = creditAssureService.findByProcessId(lastProccessId);
			if(null==creditAssure){
				ca.setProcessId(lastProccessId);
				creditAssureService.insert(ca);
			}else{
				ca.setAssureId(creditAssure.getAssureId());
				creditAssureService.update(ca);
			}			
		}
		
	}
	@Override
	public void creditAuth(Long lastProccessId) throws Exception{
		CreditAssure ca = creditAssureService.findByProcessId(lastProccessId);
		if(ca==null || "".equals(ca.getSignatureImg())){
			throw new Exception("签名提交失败！");
		}
		CreditAssure newCreditAssure = new CreditAssure();
		newCreditAssure.setAssureId(ca.getAssureId());
		newCreditAssure.setAssureStatus(AssureStatusEnum.Sign.getCode());
		creditAssureService.update(newCreditAssure);
	}

	/**
	 * 合规申请
	 * @param ca
	 * @throws Exception
	 */
	@Log
	@Override
	public void apply(CreditAssure ca) throws Exception{
		//ApplyResponse response = new ApplyResponse();
		Cust newCust = new Cust();
		newCust.setLastProccessId(ca.getProcessId());
		List<Cust> custList = custService.find(newCust);
		Cust currentCust = null;
		if (Utility.isNullOrEmpty(custList)){
			return ;
		}else{
			currentCust = custList.get(0);
		}
		// 新增客户认证流程信息
		Long lastProcessId = custList.get(0).getLastProccessId();
		// 根据lastProcessId查询身份信息认证表信息
		AuthIdentity authIdentity = authIdentityService.findByProcessId(lastProcessId);
		
		ResourceDto rsRront = ftpResourceManager.download(authIdentity.getIdFront());		
		ResourceDto rsRback = ftpResourceManager.download(authIdentity.getIdBack());
		ResourceDto rsSign = ftpResourceManager.download(ca.getSignatureImg());		
		String front = Base64Util.base64Encode(rsRront.getResourceContent());
		String back = Base64Util.base64Encode(rsRback.getResourceContent());
		String sign = Base64Util.base64Encode(rsSign.getResourceContent());		
		String signTime = ConcurrentDateUtil.formatDateTime(ca.getSignTime());
		String mobile="";
		CustAccount custAccount = new CustAccount();
		custAccount.setCustId(currentCust.getCustId());
		List<CustAccount> list = custAccountService.find(custAccount);
		if(list.size()>0){
			mobile = list.get(0).getUserName();
		}
    	//String hand = Base64Util.base64Encode(FileUtils.readFileToByteArray(FileUtils.getFile(creditCustPath+creditCust.getIdHand())));
        ComplianceApplyInfo applyInfo = new ComplianceApplyInfo(
        		currentCust.getCustName(), 
        		currentCust.getCustIdno(), 
        		currentCust.getCustMobile()==""?mobile:currentCust.getCustMobile(),
        		authIdentity.getAddress(),
        		"信用猫","","","","","","","","","","","","","","","","","","","","");
        
        ComplianceParam applyRequest = 
                new ComplianceParam(
                		currentCust.getCustName(), 
                		currentCust.getCustIdno(),
                		signTime,
                		"LOANKIND/XINYONGMAO", 
                		//Constants.BUSTYPE, 
                		"XINYONGMAO",
                    	"sign.jpg", 
                    	sign, 
                    	"上海",
	                    "front.jpg", 
	                    front, 
	                    "back.jpg", 
	                    back, 
	                    "", 
	                    "", 
	                    applyInfo);
       ComplianceApplyResponse response = foreignTradeComplianceService.creditApply(applyRequest,ca.getProductId());
        if(response.getIsSeccess()){
			CreditAssure newCreditAssure = new CreditAssure();
			newCreditAssure.setAssureId(ca.getAssureId());
			newCreditAssure.setCertNo(response.getIdentityNo());
			newCreditAssure.setApplyId(response.getApplyID());
			newCreditAssure.setAssureStatus(AssureStatusEnum.Apply.getCode());
			creditAssureService.update(newCreditAssure);
		}else{
			CreditAssure assure = new CreditAssure();
			assure.setAssureId(ca.getAssureId());
			assure.setAssureStatus(AssureStatusEnum.Fail.getCode());
			assure.setRemark("合规提交失败");
			creditAssureService.update(assure);	
			throw new Exception("合规提交失败："+response.getMessage());
		}        
	}

	/**
	 * 合规查询
	 * @param ca
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unused")
	@Override
	public QueryResponse query(CreditAssure ca) throws Exception {
		Cust newCust = new Cust();
		newCust.setLastProccessId(ca.getProcessId());
		List<Cust> custList = custService.find(newCust);
		Cust currentCust = null;
		if (Utility.isNullOrEmpty(custList)){
			return null;
		}else{
			currentCust = custList.get(0);
		}
		return null;
	}

	/**
	 * 征信状态查询
	 * @param state
	 * @param ca
	 * @throws Exception
	 */
	@Override
	public void getResult(String state,CreditAssure ca) throws Exception {
		 Cust cust = ca.getCust();
		 if(cust==null){
			 return;
		 }
		 if("5".equals(state)){
		     String result = foreignTradeComplianceService.getReport(cust.getCustIdno(),ca.getProductId()).getResult();
		     if(StringUtils.isNotBlank(result)){
		         String[] arr=StringUtils.split(result, ",");
		         String reportId=arr[0];
		         String reportSn=arr[1];
		         CreditAssure assure = new CreditAssure();
		         assure.setAssureId(ca.getAssureId());
		         assure.setReportId(reportId);
		         assure.setReportSn(reportSn);	
		         assure.setExpiredTime(ConcurrentDateUtil.formatDateTime(ConcurrentDateUtil.addDayTime(new Date(), 30)));
		         assure.setAssureStatus(AssureStatusEnum.Report.getCode());
		         assure.setRemark("征信获取成功");
		         creditAssureService.update(assure);
		         
		         AuthItem authItem = new AuthItem();
				 authItem.setAuthCode(AuthItemEnum.FOREIGN_CREDIT.getCode());
				 creditCatProcessManager.itemDone(authItem, ca.getProcessId());
				 authLogService.insert(new AuthLog(cust.getLastProccessId(), cust.getCustId(),
						 AuthItemEnum.FOREIGN_CREDIT.getCode(), assure.getExpiredTime(), new Date()));
		     }
		 }else if("7".equals(state)){//征信空白      授信拒绝
			 CreditAssure assure = new CreditAssure();
			 assure.setAssureId(ca.getAssureId());
			 assure.setAssureStatus(AssureStatusEnum.Fail.getCode());
			 assure.setRemark("征信空白");
			 creditAssureService.update(assure);	    		
		 }else if("4".equals(state)){
			 CreditAssure assure = new CreditAssure();
			 assure.setAssureId(ca.getAssureId());
			 assure.setAssureStatus(AssureStatusEnum.Fail.getCode());
			 assure.setRemark("征信解析失败");
			 creditAssureService.update(assure);
		 }
	}

	/**
	 * 征信提交
	 * @param ca
	 * @throws Exception
	 */
	@Override
	public void creditSubmit(CreditAssure ca) throws Exception {
		int foreignCreditOpenFlag = getCreditChoice(ca.getProductId());
		if(foreignCreditOpenFlag==1){
			foreignSubmit(ca);
		}else{
			assureSubmit(ca);
		}
		
	}
		
	public void foreignSubmit(CreditAssure ca) throws Exception{
		ForeignSubmitParam param = new ForeignSubmitParam();
		Cust cust = ca.getCust();
		if(cust==null){
			return;
		}
		param.setApplyID(ca.getApplyId());
		String busType = "";
		for(ProductBusTypeEnum e :ProductBusTypeEnum.values()){
			if( e.getId()== ca.getProductId()){
				busType=e.getBusType();
			}
		}
		param.setBusType(busType);
		param.setCifName(cust.getCustName());
		param.setCrpReason(AssureParams.QueryReason.LOANAUDIT);
		param.setCzAuth("1"); //是否授权（1 是，0 否）
		param.setCzId("1"); //是否有身份证信息（1 是，0否）
		param.setIdNo(cust.getCustIdno());
		param.setIdType(AssureParams.CertType.IDCARD);
		ReportStateResponse res =foreignTradeComplianceService.foreignSubmit(param);
		if(res.getStatusCode()==0){
			CreditAssure assure = new CreditAssure();
			assure.setAssureId(ca.getAssureId());
			assure.setAssureStatus(AssureStatusEnum.Assure_Submit.getCode());
			creditAssureService.update(assure);
		}else if(res.getStatusCode()==1){
			CreditAssure assure = new CreditAssure();
			assure.setAssureId(ca.getAssureId());
			assure.setAssureStatus(AssureStatusEnum.Fail.getCode());
			creditAssureService.update(assure);	
			assure.setRemark("外贸征信提交失败");
			throw new Exception("征信提交失败："+res.getResult());
		}	
	}
	
	public void assureSubmit(CreditAssure ca) throws Exception{
		AssureSubmitParam param = new AssureSubmitParam();
		Cust cust = ca.getCust();
		if(cust==null){
			return;
		}
		param.setApplyID(ca.getApplyId());
		
		String busType = "";
		for(ProductBusTypeEnum e :ProductBusTypeEnum.values()){
			if( e.getId()== ca.getProductId()){
				busType=e.getBusType();
			}
		}
		param.setBusType(busType);
		param.setName(cust.getCustName());
		param.setQueryReason(AssureParams.QueryReason.ASSUREQUALIFICATION);		
		param.setCertNo(cust.getCustIdno());
		param.setCertType(AssureParams.CertType.IDCARD);
		AssureSubmitResponse res =foreignTradeComplianceService.assureSubmit(param);
		if(res.getStatusCode()==0){
			CreditAssure assure = new CreditAssure();
			assure.setAssureId(ca.getAssureId());
			assure.setAssureStatus(AssureStatusEnum.Assure_Submit.getCode());
			creditAssureService.update(assure);
		}else if(res.getStatusCode()==1){
			CreditAssure assure = new CreditAssure();
			assure.setAssureId(ca.getAssureId());
			assure.setAssureStatus(AssureStatusEnum.Fail.getCode());
			assure.setRemark("担保征信提交失败");
			creditAssureService.update(assure);	
			throw new Exception("征信提交失败："+res.getResult());
		}		
	}

	/**
	 * 征信报告查询
	 * @param ca
	 * @throws Exception
	 */
	@Override
	public void toGetResult(CreditAssure ca) throws Exception {
		Cust cust = ca.getCust();
		if(cust==null){
			return;
		}
		ReportStateResponse res = foreignTradeComplianceService.getState(cust.getCustIdno(),ca.getProductId());
		if(res.getStatusCode()==0){
			String state = res.getResult();
			if("5".equals(state)){
			     String result = foreignTradeComplianceService.getReport(cust.getCustIdno(),ca.getProductId()).getResult();
			     if(StringUtils.isNotBlank(result)){
			         String[] arr=StringUtils.split(result, ",");
			         String reportId=arr[0];
			         String reportSn=arr[1];
			         CreditAssure assure = new CreditAssure();
			         assure.setAssureId(ca.getAssureId());
			         assure.setReportId(reportId);
			         assure.setReportSn(reportSn);	
			         assure.setExpiredTime(ConcurrentDateUtil.formatDateTime(ConcurrentDateUtil.addDayTime(new Date(), 30)));
			         assure.setAssureStatus(AssureStatusEnum.Report.getCode());
			         assure.setRemark("征信获取成功");
			         creditAssureService.update(assure);
			         
			         AuthItem authItem = new AuthItem();
					 authItem.setAuthCode(AuthItemEnum.FOREIGN_CREDIT.getCode());
					 creditCatProcessManager.itemDone(authItem, ca.getProcessId());
					 authLogService.insert(new AuthLog(cust.getLastProccessId(), cust.getCustId(),
							 AuthItemEnum.FOREIGN_CREDIT.getCode(), assure.getExpiredTime(), new Date()));
			     }
			 }else if("7".equals(state)){//征信空白      授信拒绝
				 CreditAssure assure = new CreditAssure();
				 assure.setAssureId(ca.getAssureId());
				 assure.setAssureStatus(AssureStatusEnum.Fail.getCode());
				 assure.setRemark("征信空白");
				 creditAssureService.update(assure);
			
			 }else if("3".equals(state)){
				 Date createTime = ca.getCreateTime();
                 Date nowDate = new Date();
                 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                 String nowStr = format.format(nowDate);
                 String createStr = format.format(createTime);
                 //如果是当天查询失败了，暂不做处理
                 if(!nowStr.equals(createStr)){
                	 CreditAssure assure = new CreditAssure();
    				 assure.setAssureId(ca.getAssureId());
    				 assure.setAssureStatus(AssureStatusEnum.Fail.getCode());
    				 assure.setRemark("征信查询失败");
    				 creditAssureService.update(assure);
                 }				 
			 }else if("4".equals(state)){
				 CreditAssure assure = new CreditAssure();
				 assure.setAssureId(ca.getAssureId());
				 assure.setAssureStatus(AssureStatusEnum.Fail.getCode());
				 assure.setRemark("征信解析失败");
				 creditAssureService.update(assure);
			 }
		}
	}
	@Override
	public void preAudit(CreditAssure ca) throws Exception {		
		Cust cust = ca.getCust();
		Long processId = cust.getLastProccessId();
		
		PreAuditParam param = new PreAuditParam();
		InputVbs input = new InputVbs();
		int zmxyScore = -1;
		AuthSecredit temp = new AuthSecredit();
		temp.setProcessId(processId);
		List<AuthSecredit> list = authSecreditService.find(temp);
		if(list.size()>0){
			String score = list.get(0).getZmxyScore();
			if(!StringUtil.isEmpty(score)){
				zmxyScore = Integer.parseInt(score);
			}			
		}
		input.setZhimaCredit(zmxyScore);
		
		AuthPersonalInfo info = authPersonalInfoService.findByProcessId(processId);
		if(info==null){
			throw new Exception("个人信息不存在");
		}
		input.setFrontEducation(info.getEducationValue());
		input.setEducation(info.getEducationValue()); //??待定
		
		// 根据用户和产品获取手机认证信息
		AuthMobile mobile = authMobileService.findByCustAndProduct(cust,ca.getProductId());		
		if(null == mobile){
			throw new Exception("手机信息不存在");
		}
				
		if(MobileStatusEnum.REAL_NAME.getCode() != mobile.getResultStatus() ){
			if(ca.getSignTime().getTime() < ConcurrentDateUtil.addDayTime(new Date(), -2).getTime()){
				 CreditAssure assure = new CreditAssure();
				 assure.setAssureId(ca.getAssureId());
				 assure.setAssureStatus(AssureStatusEnum.Fail.getCode());
				 assure.setRemark("手机认证时间过长，需重新认证");
				 creditAssureService.update(assure);
				 return;
			}
			throw new Exception("手机尚未实名");
		}else {
			if(mobile.getExpiredTime()!=null && mobile.getExpiredTime()!=""){
				Date expiredDate = ConcurrentDateUtil.strToDate(mobile.getExpiredTime());
				if(expiredDate.getTime() < new Date().getTime()){
					throw new Exception("手机认证已失效");
				}
			}
			
		}
		
		input.setRegionOnline(mobile.getCity());
		
		String idNo = cust.getCustIdno();
		if(StringUtils.isBlank(idNo)){
			throw new Exception("身份证号不存在");
		}
		String sex ;
		if("M".equalsIgnoreCase(IdcardUtils.getGenderByIdCard(idNo))){
			sex ="男";
		}else if ("F".equalsIgnoreCase(IdcardUtils.getGenderByIdCard(idNo))){
			sex = "女";
		}else {
			sex = "未知";
		}
		input.setSex(sex);
		int age = IdcardUtils.getAge(idNo);
		input.setAge(age);
		if(ca.getProductId()==null || ca.getProductId()==0){
			 CreditAssure assure = new CreditAssure();
			 assure.setAssureId(ca.getAssureId());
			 assure.setAssureStatus(AssureStatusEnum.Fail.getCode());
			 assure.setRemark("productId不存在，重新认证机构版征信");
			 creditAssureService.update(assure);
			 return;
		}

		String productName = "";
		String busType = "";
		for(ProductBusTypeEnum e :ProductBusTypeEnum.values()){
			if( e.getId()== ca.getProductId()){
				busType=e.getBusType();
				productName = e.getName();
			}
		}
		input.setCaller(productName);
		String inputStr = JacksonUtil.Obj2Json(input);
		param.setInputVbs(inputStr);
		
		DynamicParams dynamicParams = new DynamicParams();
		dynamicParams.setId(mobile.getMobileId());
		dynamicParams.setIdentity(cust.getCustIdno());
		dynamicParams.setName(cust.getCustName());
		dynamicParams.setMobile(mobile.getMobile());		
		dynamicParams.setBusType(busType);
		String dynamicParamStr = JacksonUtil.Obj2Json(dynamicParams);
		param.setDynamicParams(dynamicParamStr);
		param.setCallFrom(productName);
//		param.setEngineType("VRC");
//		param.setModuleName("征信预审");
		
		CreditAssure assure = new CreditAssure();
		assure.setAssureId(ca.getAssureId());
		PreAuditResponse res = foreignTradeComplianceService.preAudit(param,idNo);		
		if(res.getDecisionCode()==0){
			if("通过".equals(res.getDecisionResult())){
				assure.setAssureStatus(AssureStatusEnum.PreAuditSuccess.getCode());
				List<ScoreInfo> listScore = res.getScoreInfos();
				ScoreInfo score = new ScoreInfo() ;
				if(listScore.size()>0){
					 score = listScore.get(listScore.size()-1);
				}				
				assure.setMobileScore(score.getScorevalue());
				assure.setScoreModuleName(score.getModulename());
				assure.setScoreName(score.getScorename());
			}else{
				assure.setAssureStatus(AssureStatusEnum.PreAuditFail.getCode());
				assure.setRemark("征信预审拒绝");
				assure.setExpiredTime(ConcurrentDateUtil.formatDateTime(ConcurrentDateUtil.addDayTime(new Date(), 30)));
			}
			 			
		}else{
			 assure.setAssureStatus(AssureStatusEnum.PreAuditFail.getCode());
			 assure.setRemark("征信预审失败");
			 assure.setExpiredTime(ConcurrentDateUtil.formatDateTime(ConcurrentDateUtil.addDayTime(new Date(), 30)));
		}		
		creditAssureService.update(assure);
	}
	
	/**根据枚举值确定走担保还是外贸版征信，默认外贸
	 * 
	 * @param productId
	 * @return
	 */
	public int getCreditChoice(Long productId){
		if(productId !=null){						
			for(ProductBusTypeEnum e : ProductBusTypeEnum.values()){
				if(productId == e.getId()){
					return e.getCreditChoice();
				}
			}
		}
		return 1;
	}
	
}

